/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controle.gui.frames.internos;

import controle.gui.frames.ControleFramePrincipal;
import controle.gui.utils.ApagaElementosDaInterface;
import controle.gui.utils.EnabledGUIElements;
import controle.gui.utils.TamanhoJTextField;
import controle.gui.utils.setEnabledGUIElements;
import controle.interfaces.Constantes;
import gui.frames.internos.IFMunicipios;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import modelo.Municipio;
import persistencia.dao.AbstractDAO;
import persistencia.dao.TransacaoDAO;

/**
 *
 * @author Maycon Fernando Silva Brito
 * @author mayconfsbrito@gmail.com
 */
public class ControleMunicipios {

    /*
     * Variáveis da classe
     */
    private IFMunicipios frame = null;

    /*
     * Construtor da classe
     */
    public ControleMunicipios(IFMunicipios frame) {
        this.frame = frame;
    }

    /**
     * Inicializa o frame
     */
    public void inicializa() {

        //Torna o frame visível
        frame.setVisible(true);

        //Limita o tamanho do JTextField
        TamanhoJTextField.limitaTamanho(new int[]{100}, frame.textNome);

        this.limparGUI();

        //Inicializa eventos da tabela
        frame.tabela.getSelectionModel().addListSelectionListener(frame.listener);
        frame.tabela.getColumnModel().getSelectionModel().addListSelectionListener(frame.listener);

    }

    /**
     * Especificações em @InternalFrame
     */
    public void guiAtiva(boolean estado) {
        if (estado) {
            setEnabledGUIElements.enabledJComponent(frame.buttonCadastro);
            setEnabledGUIElements.disabledJComponent(frame.buttonAlterar);

        } else {
            setEnabledGUIElements.enabledJComponent(frame.buttonAlterar);
            setEnabledGUIElements.disabledJComponent(frame.buttonCadastro);
        }
    }

    /**
     * Verifica o acesso do usuário para utilizar o frame
     */
    protected void verificaAcessos() {

        //Verifica a permissao de @user para este frame
        if (!ControleFramePrincipal.acessos.get(Constantes.PERMISSAO_CADASTRA_ALTERA_LOCAIS).isAcesso()) {
            EnabledGUIElements.disabledJComponent(frame.buttonCadastro, frame.buttonAlterar);
        }
    }

    /**
     * Limpa os componentes do frame
     */
    public void limparGUI() {

        frame.tabela.clearSelection();
        //this.listarPesquisaNaTabela(null);
        new ApagaElementosDaInterface().apagaJTextField(frame.textId, frame.textCodigo, frame.textNome);
        frame.comboEstado.setSelectedIndex(0);

        //Configura o comportamento da gui de acordo com as permissões do usuário
        this.guiAtiva(true);
        this.verificaAcessos();
    }

    /**
     * Preenche todos os componentes da GUI a partir do objeto selecionado na tabela
     */
    public void tabelaPreencheGUI() {

        int linha = frame.tabela.getSelectedRow();
        Integer cod;
        try {
            cod = (Integer) frame.tabela.getValueAt(linha, 0);
        } catch (IndexOutOfBoundsException er) {
            cod = 0;
            return;
        }

        List<Municipio> consulta = AbstractDAO.consultar("Municipio", "idMunicipio=" + cod);

        if (consulta.size() > 0) {
            Municipio m = consulta.get(0);
            frame.textId.setText(Integer.toString(m.getIdMunicipio()));
            frame.textCodigo.setText(m.getCodigo());
            frame.textNome.setText(m.getNome());
            frame.comboEstado.setSelectedItem(m.getEstado());

            //Configura o comportamento dos botões da interface
            frame.buttonCadastro.setEnabled(false);
            EnabledGUIElements.enabledJComponent(frame.buttonAlterar);
            this.guiAtiva(false);
            this.verificaAcessos();

        }
    }

    /**
     * Especificações do método em @InternalFrame
     */
    protected void listarTodosElementosNaTabela() {

        List<Municipio> list = AbstractDAO.listar("Municipio");
        listarPesquisaNaTabela(list);
    }

    /**
     * Especificações do método em @InternalFrame
     */
    private void listarPesquisaNaTabela(List<Municipio> list) {

        frame.tabela.getColumnModel().getColumn(0).setPreferredWidth(10);
        frame.tabela.getColumnModel().getColumn(1).setPreferredWidth(20);
        frame.tabela.getColumnModel().getColumn(2).setPreferredWidth(80);
        frame.tabela.getColumnModel().getColumn(3).setPreferredWidth(10);

        DefaultTableModel modelo = (DefaultTableModel) frame.tabela.getModel();
        modelo.setNumRows(0);
        limparGUI();

        try {
            if (list != null) {
                for (int i = 0; i < list.size(); i++) {
                    Municipio mun = list.get(i);
                    modelo.addRow(new Object[]{mun.getIdMunicipio(), mun.getCodigo(), mun.getNome(), mun.getEstado()});
                }
            }
        } catch (Exception er) {
            JOptionPane.showMessageDialog(frame, "Erro ao listar os objetos na tabela!\n\n" + er, "Erro na listagem!", JOptionPane.ERROR_MESSAGE);
            er.printStackTrace();
        }

        //Permite o evento de ordernar a tabela a partir do click do mouse
        frame.tabela.setAutoCreateRowSorter(true);
    }

    /**
     * Instancia o municipio a partir dos elementos da interface gráfica
     *
     * @return
     */
    public Municipio criaMunicipio(int opcao) {

        //Caso o usuário confirme o evento
        if (opcao == JOptionPane.YES_OPTION) {

            //Verifica se o nome do município está preenchido
            if (!frame.textNome.getText().trim().isEmpty()) {

                //Verifica se o código foi preenchido
                if (!frame.textCodigo.getText().trim().isEmpty()) {

                    //Verifica se o código do município tem 7 dígitos
                    if(frame.textCodigo.getText().trim().length() != 7){
                        JOptionPane.showMessageDialog(frame, "Atenção! O código do município deve ter 7 dígitos.", "Código do município!", JOptionPane.WARNING_MESSAGE);
                        return null;
                    }
                    
                    //Verifica se o estado do município foi selecionado
                    if (frame.comboEstado.getSelectedIndex() != 0) {

                        //Instancia as variáveis
                        String codigo = frame.textCodigo.getText();
                        String nome = frame.textNome.getText();
                        String estado = frame.comboEstado.getSelectedItem().toString();
                        Municipio mun = new Municipio(codigo, nome, estado);

                        //Verifica o id do município
                        if (!frame.textId.getText().trim().isEmpty()) {
                            mun.setIdMunicipio(Integer.parseInt(frame.textId.getText().trim()));
                        } else {
                            mun.setIdMunicipio(AbstractDAO.max(Municipio.class, "idMunicipio") + 1);
                        }
                        
                        //Verifica se as restrições de código estão sendo respeitadas
                        if (this.verificaCodigoRepetido(mun)) {
                            JOptionPane.showMessageDialog(frame, "Atenção! Já existe um município cadastrado com o mesmo código.", "Código repetido!", JOptionPane.WARNING_MESSAGE);
                            return null;
                        }

                        //Retorna o objeto
                        return mun;

                    } else {
                        JOptionPane.showMessageDialog(frame, "Atenção! O estado do município deve ser selecionado.", "Estado não selecionado!", JOptionPane.WARNING_MESSAGE);
                    }

                } else {
                    JOptionPane.showMessageDialog(frame, "Atenção! O codigo do município deve ser preenchido.", "Codigo não preenchido!", JOptionPane.WARNING_MESSAGE);

                }

            } else {
                JOptionPane.showMessageDialog(frame, "Atenção! O nome do município deve ser preenchido.", "Nome não preenchido!", JOptionPane.WARNING_MESSAGE);

            }
        }
        return null;

    }

    /**
     * Cadastra um município através do frame
     */
    public void cadastrar() {

        //Pergunta ao usuário se ele deseja realizar o cadastro
        int opcao = JOptionPane.showOptionDialog(frame, "Tem certeza que deseja cadastrar " + frame.textNome.getText()
                + "?", "Cadastro de município", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, frame.botoesOpcoes, frame.botoesOpcoes[0]);

        //Captura o objeto no frame
        Municipio mun = this.criaMunicipio(opcao);

        //Realiza o cadastro
        if (mun != null) {
            if (AbstractDAO.cadastrar(mun)) {
                JOptionPane.showMessageDialog(frame, "Município cadastrado com sucesso!", "Cadastro.", JOptionPane.INFORMATION_MESSAGE);
                this.limparGUI();
                this.buscar();
                
                int id = AbstractDAO.max(Municipio.class, "idMunicipio");
                TransacaoDAO.cadastrar("Cadastrou o município código=" + mun.getCodigo() + " id=" + id);
            }
        }

    }

    /**
     * Altera um município através do frame
     */
    public void alterar() {

        //Pergunta ao usuário se ele deseja realizar o cadastro
        int opcao = JOptionPane.showOptionDialog(frame, "Tem certeza que deseja alterar o município " + frame.textNome.getText()
                + "?", "Alteração de município", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, frame.botoesOpcoes, frame.botoesOpcoes[0]);

        //Captura o objeto no frame
        Municipio mun = this.criaMunicipio(opcao);

        //Realiza o cadastro
        if (mun != null) {
            if (AbstractDAO.alterar(mun)) {
                JOptionPane.showMessageDialog(frame, "Município Alterado com sucesso!", "Alteração.", JOptionPane.INFORMATION_MESSAGE);
                this.limparGUI();
                this.buscar();
                
                TransacaoDAO.cadastrar("Alterou o município código=" + mun.getCodigo() + " id=" + mun.getIdMunicipio());
            }
        }

    }

    /**
     * Exclui um município através do frame
     */
    public void excluir() {

        /*
         * Pergunta ao usuário se ele deseja realizar o cadastro
         */
        int opcao = JOptionPane.showOptionDialog(frame, "Tem certeza que deseja excluir o município " + frame.textNome.getText()
                + "?", "Exclusão de município", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, frame.botoesOpcoes, frame.botoesOpcoes[0]);

        /*
         * Captura o objeto no frame
         */
        Municipio mun = this.criaMunicipio(opcao);

        /*
         * Realiza o cadastro
         */
        if (mun != null) {
            if (AbstractDAO.excluir(mun)) {
                JOptionPane.showMessageDialog(frame, "Município excluído com sucesso!", "Exclusão.", JOptionPane.INFORMATION_MESSAGE);
                this.limparGUI();
                this.buscar();
            }
        }

    }

    /**
     * Realiza a busca de um determinado objeto a partir dos parâmetros definidos no @frame
     */
    public void buscar() {

        //Captura os parametros do frame
        String codigo = frame.textBuscaCodigo.getText();
        String estado = frame.comboBuscaEstado.getSelectedItem().toString();
        String nome = frame.textBuscaNome.getText();

        //Realiza a busca no bd
        //Captura o id do logradouro caso ele tenha sido selecionado
        List<Municipio> list = null;

        //Incrementa a string para consutar a busca
        String query = "";
        if (codigo != null && !codigo.trim().equals("")) {
            query += "codigo like '%" + codigo + "%'";
        }
        if (estado != null && !estado.equals("Selecione...")) {
            if (query.length() > 1) {
                query += " AND ";
            }
            query += " estado='" + estado + "'";
        }
        if (nome != null && !nome.trim().equals("")) {
            if (query.length() > 1) {
                query += " AND ";
            }
            query += " nome like '%" + nome + "%'";
        }

        if (!query.equals("")) {
            //System.out.println(query);
            list = AbstractDAO.consultar("Municipio", query);
        }

        //Lista os objetos encontrados na tabela
        if (list != null) {
            this.listarPesquisaNaTabela(list);
        } else {
            this.listarPesquisaNaTabela(null);
        }
    }

    /**
     * Limpa apenas os componentes de busca e lista a tabela de objetos com todos os objetos do bd
     */
    public void limparBusca() {

        new ApagaElementosDaInterface().apagaJTextField(frame.textBuscaCodigo, frame.textBuscaNome);
        frame.comboBuscaEstado.setSelectedIndex(0);
        this.listarPesquisaNaTabela(null);

    }

    /**
     * Verifica se as restrições de código do objeto estão sendo respeitadas
     *
     * @return
     */
    public boolean verificaCodigoRepetido(Municipio mun) {

        //Captura no Bd as quadras com o mesmo código e mesma localidade
        List<Municipio> list = AbstractDAO.consultar("Municipio", "codigo='" + mun.getCodigo() + "' AND idMunicipio!=" + mun.getIdMunicipio());
        if (!list.isEmpty()) {
            return true;
        }

        return false;
    }
}
